"""
参数配置管理模块
负责工具字典的初始化、管理和存储
"""

import traceback
from typing import Dict, Any

from config.logging_config import get_logger

logger = get_logger(__name__)


class ToolDictConfig:
    """参数配置管理器"""

    def __init__(self):
        self.base_tools_dict: Dict[str, Dict[str, Any]] = {}
        self.mcp_tools_dict: Dict[str, Dict[str, Any]] = {}
        self._initialized = False

    async def init_global_tools_dict(self):
        """初始化全局工具字典"""
        try:
            print("🔧 正在初始化全局工具字典...")

            # 延迟导入避免循环依赖
            from config.database import get_db_session

            session = next(get_db_session())
            try:
                # 1. 初始化基础工具字典
                await self._init_base_tools_dict(session)

                # 2. 初始化MCP工具字典
                await self._init_mcp_tools_dict(session)

                # 3. 标记为已初始化
                self._initialized = True

                print(f"✅ 全局工具字典初始化完成")
                print(f"   📦 基础工具数量: {len(self.base_tools_dict)}")
                print(f"   🔌 MCP工具数量: {len(self.mcp_tools_dict)}")
            finally:
                session.close()

        except Exception as e:
            print(f"❌ 全局工具字典初始化失败: {e}")
            print(f"   详细错误: {traceback.format_exc()}")
            # 即使失败也要确保有空字典
            self.base_tools_dict = {}
            self.mcp_tools_dict = {}
            self._initialized = False

    async def _init_base_tools_dict(self, session):
        """初始化基础工具字典"""
        self.base_tools_dict = {}

        # 获取所有启用的基础工具
        from pojo.ai_web_detail_tools_model import AIWebDetailToolsModel
        base_tools = session.query(AIWebDetailToolsModel).filter(
            AIWebDetailToolsModel.tool_type == 1,  # 基础工具
            AIWebDetailToolsModel.is_enabled == True
        ).all()

        for tool in base_tools:
            tool_name = tool.tool_name
            server_code = tool.server_code  # 获取服务代码

            # 解析工具参数
            params_info = {}
            if tool.parameters:
                try:
                    # 处理参数数据：可能是字符串、字典或列表
                    parameters_data = tool.parameters

                    # 如果是字符串，尝试解析为JSON
                    if isinstance(parameters_data, str):
                        import json
                        try:
                            parameters_data = json.loads(parameters_data)
                        except json.JSONDecodeError:
                            print(f"⚠️ 工具 {tool_name} 的参数不是有效的JSON格式: {parameters_data}")
                            parameters_data = []

                    # 如果是字典，转换为列表格式
                    if isinstance(parameters_data, dict):
                        # 如果是 JSON Schema 格式
                        if 'properties' in parameters_data:
                            properties = parameters_data['properties']
                            required = parameters_data.get('required', [])
                            parameters_list = []
                            for param_name, param_config in properties.items():
                                parameters_list.append({
                                    'param_name': param_name,
                                    'param_type': param_config.get('type', 'string'),
                                    'description': param_config.get('description', ''),
                                    'is_required': param_name in required,
                                    'default_value': param_config.get('default')
                                })
                            parameters_data = parameters_list
                        else:
                            # 如果是其他字典格式，转换为列表
                            parameters_data = [parameters_data]

                    # 现在 parameters_data 应该是列表格式
                    if isinstance(parameters_data, list):
                        for param in parameters_data:
                            if isinstance(param, dict):
                                param_name = param.get('param_name', '')
                                if param_name:  # 只有参数名存在才添加
                                    params_info[param_name] = {
                                        'param_type': param.get('param_type', 'string'),
                                        'description': param.get('description', ''),
                                        'is_required': param.get('is_required', False),
                                        'default_value': param.get('default_value')
                                    }
                            else:
                                print(f"⚠️ 工具 {tool_name} 的参数项不是字典格式: {param}")
                    else:
                        print(f"⚠️ 工具 {tool_name} 的参数格式不支持: {type(parameters_data)}")

                except Exception as e:
                    print(f"⚠️ 解析工具 {tool_name} 参数时出错: {e}")
                    print(f"   原始参数数据: {tool.parameters}")
                    print(f"   参数数据类型: {type(tool.parameters)}")

            self.base_tools_dict[tool.id] = {
                'tool_id': tool.id,
                'tool_name': tool_name,
                'server_code': server_code,  # 添加服务代码
                'description': tool.description or '',
                'params': params_info,  # execute.py 需要的参数结构
                'parent_id': tool.parent_id,
                'tool_type': tool.tool_type,
                'human_interactive_flag': tool.human_interactive_flag
            }

    async def _init_mcp_tools_dict(self, session):
        """初始化MCP工具字典"""
        self.mcp_tools_dict = {}

        # 获取所有启用的MCP工具
        from pojo.ai_web_mcp_tools_model import AIWebMCPToolsModel
        from pojo.ai_web_detail_tools_model import AIWebDetailToolsModel

        mcp_tools = session.query(AIWebMCPToolsModel).filter(
            AIWebMCPToolsModel.status == 1  # 启用状态
        ).all()

        for mcp_tool in mcp_tools:
            # 获取该MCP下的详细工具
            detail_tools = session.query(AIWebDetailToolsModel).filter(
                AIWebDetailToolsModel.parent_id == mcp_tool.id,
                AIWebDetailToolsModel.tool_type == 2,  # MCP工具
                AIWebDetailToolsModel.is_enabled == True
            ).all()

            for detail_tool in detail_tools:
                mcp_key = f"{mcp_tool.mcp_name}.{detail_tool.tool_name}"
                server_code = detail_tool.server_code  # 获取服务代码

                # 解析工具参数
                params_info = {}
                if detail_tool.parameters:
                    try:
                        # 处理参数数据：可能是字符串、字典或列表
                        parameters_data = detail_tool.parameters

                        # 如果是字符串，尝试解析为JSON
                        if isinstance(parameters_data, str):
                            import json
                            try:
                                parameters_data = json.loads(parameters_data)
                            except json.JSONDecodeError:
                                print(f"⚠️ MCP工具 {mcp_key} 的参数不是有效的JSON格式: {parameters_data}")
                                parameters_data = []

                        # 如果是字典，转换为列表格式
                        if isinstance(parameters_data, dict):
                            # 如果是 JSON Schema 格式
                            if 'properties' in parameters_data:
                                properties = parameters_data['properties']
                                required = parameters_data.get('required', [])
                                parameters_list = []
                                for param_name, param_config in properties.items():
                                    parameters_list.append({
                                        'param_name': param_name,
                                        'param_type': param_config.get('type', 'string'),
                                        'description': param_config.get('description', ''),
                                        'is_required': param_name in required,
                                        'default_value': param_config.get('default')
                                    })
                                parameters_data = parameters_list
                            else:
                                # 如果是其他字典格式，转换为列表
                                parameters_data = [parameters_data]

                        # 现在 parameters_data 应该是列表格式
                        if isinstance(parameters_data, list):
                            for param in parameters_data:
                                if isinstance(param, dict):
                                    param_name = param.get('param_name', '')
                                    if param_name:  # 只有参数名存在才添加
                                        params_info[param_name] = {
                                            'param_type': param.get('param_type', 'string'),
                                            'description': param.get('description', ''),
                                            'is_required': param.get('is_required', False),
                                            'default_value': param.get('default_value')
                                        }
                                else:
                                    print(f"⚠️ MCP工具 {mcp_key} 的参数项不是字典格式: {param}")
                        else:
                            print(f"⚠️ MCP工具 {mcp_key} 的参数格式不支持: {type(parameters_data)}")

                    except Exception as e:
                        print(f"⚠️ 解析MCP工具 {mcp_key} 参数时出错: {e}")
                        print(f"   原始参数数据: {detail_tool.parameters}")
                        print(f"   参数数据类型: {type(detail_tool.parameters)}")

                self.mcp_tools_dict[detail_tool.id] = {
                    'mcp_service': mcp_tool.mcp_name,  # mcpCalling需要的参数
                    'tool_name': detail_tool.tool_name,  # mcpCalling需要的参数
                    'server_code': server_code,  # 添加服务代码
                    'parameters': params_info,  # mcpCalling需要的参数结构
                    'description': detail_tool.description or '',
                    'mcp_id': mcp_tool.id,
                    'tool_id': detail_tool.id,
                    'mcp_config': mcp_tool.json_schema,
                    'human_interactive_flag': detail_tool.human_interactive_flag
                }

    def get_base_tools_dict(self, server_code: str = None) -> Dict[str, Dict[str, Any]]:
        """获取基础工具字典
        
        Args:
            server_code: 可选，服务代码筛选条件。如果提供，只返回匹配的工具
            
        Returns:
            基础工具字典，key为tool_id，value为工具信息
        """
        if server_code is None:
            # 如果没有指定server_code，返回所有基础工具
            return self.base_tools_dict

        # 根据server_code筛选基础工具
        filtered_tools = {}
        for tool_id, tool_info in self.base_tools_dict.items():
            if tool_info.get('server_code') == server_code:
                filtered_tools[tool_id] = tool_info

        return filtered_tools

    def get_mcp_tools_dict(self, server_code: str = None) -> Dict[str, Dict[str, Any]]:
        """获取MCP工具字典
        
        Args:
            server_code: 可选，服务代码筛选条件。如果提供，只返回匹配的工具
            
        Returns:
            MCP工具字典，key为tool_id，value为工具信息
        """
        if server_code is None:
            # 如果没有指定server_code，返回所有MCP工具
            return self.mcp_tools_dict

        # 根据server_code筛选MCP工具
        filtered_tools = {}
        for tool_id, tool_info in self.mcp_tools_dict.items():
            if tool_info.get('server_code') == server_code:
                filtered_tools[tool_id] = tool_info

        return filtered_tools

    def set_base_tools_dict(self, tools_dict: Dict[str, Dict[str, Any]]):
        """设置基础工具字典"""
        self.base_tools_dict = tools_dict

    def set_mcp_tools_dict(self, mcp_dict: Dict[str, Dict[str, Any]]):
        """设置MCP工具字典"""
        self.mcp_tools_dict = mcp_dict

    def is_initialized(self) -> bool:
        """检查是否已初始化"""
        return self._initialized

    def get_stats(self) -> Dict[str, Any]:
        """获取统计信息"""
        return {
            "initialized": self._initialized,
            "base_tools_count": len(self.base_tools_dict),
            "mcp_tools_count": len(self.mcp_tools_dict),
            "total_tools_count": len(self.base_tools_dict) + len(self.mcp_tools_dict)
        }

    def get_base_tool_info(self, tool_id: int) -> Dict[str, Any]:
        """根据tool_id获取基础工具信息
        
        Args:
            tool_id: 工具ID
            
        Returns:
            工具信息字典
        """
        return self.base_tools_dict.get(tool_id, {})

    def get_base_tool_info_by_name(self, tool_name: str, server_code: str = None) -> Dict[str, Any]:
        """根据工具名称获取基础工具信息
        
        Args:
            tool_name: 工具名称
            server_code: 可选，服务代码筛选条件
            
        Returns:
            工具信息字典，如果找到多个匹配则返回第一个
        """
        for tool_id, tool_info in self.base_tools_dict.items():
            if tool_info.get('tool_name') == tool_name:
                if server_code is None or tool_info.get('server_code') == server_code:
                    return tool_info
        return {}

    def get_mcp_tool_info(self, tool_id: int) -> Dict[str, Any]:
        """根据tool_id获取MCP工具信息
        
        Args:
            tool_id: 工具ID
            
        Returns:
            工具信息字典
        """
        return self.mcp_tools_dict.get(tool_id, {})

    def get_mcp_tool_info_by_name(self, tool_name: str, server_code: str = None) -> Dict[str, Any]:
        """根据工具名称获取MCP工具信息
        
        Args:
            tool_name: 工具名称
            server_code: 可选，服务代码筛选条件
            
        Returns:
            工具信息字典，如果找到多个匹配则返回第一个
        """
        for tool_id, tool_info in self.mcp_tools_dict.items():
            if tool_info.get('tool_name') == tool_name:
                if server_code is None or tool_info.get('server_code') == server_code:
                    return tool_info
        return {}

    def get_mcp_calling_params(self, tool_id: int = None, tool_name: str = None, server_code: str = None) -> Dict[
        str, Any]:
        """获取MCP工具调用参数（用于mcpCalling）
        
        Args:
            tool_id: 工具ID（优先级最高）
            tool_name: 工具名称
            server_code: 服务代码
            
        Returns:
            MCP调用参数字典
        """
        mcp_info = {}

        if tool_id:
            # 优先使用tool_id
            mcp_info = self.mcp_tools_dict.get(tool_id, {})

        if not mcp_info:
            return {}

        return {
            "mcp_service": mcp_info.get("mcp_service", ""),
            "tool_name": mcp_info.get("tool_name", ""),
            "parameters": mcp_info.get("parameters", {})
        }

    def get_base_tool_params(self, tool_id: int = None, tool_name: str = None, server_code: str = None) -> Dict[
        str, Any]:
        """获取基础工具参数结构（用于execute）
        
        Args:
            tool_id: 工具ID（优先级最高）
            tool_name: 工具名称
            server_code: 服务代码
            
        Returns:
            基础工具参数字典
        """
        base_info = {}

        if tool_id:
            # 优先使用tool_id
            base_info = self.base_tools_dict.get(tool_id, {})
        if not base_info:
            return {}

        return {
            "tool_name": base_info.get("tool_name", ""),
            "params": base_info.get("params", {})
        }

    def search_tools_by_keyword(self, keyword: str) -> Dict[str, Any]:
        """按关键词搜索工具"""
        keyword_lower = keyword.lower()

        # 搜索基础工具
        base_matches = []
        for tool_id, tool_info in self.base_tools_dict.items():
            tool_name = tool_info.get('tool_name', '')
            description = tool_info.get('description', '')
            server_code = tool_info.get('server_code', '')

            if (keyword_lower in tool_name.lower() or
                    keyword_lower in description.lower() or
                    keyword_lower in server_code.lower()):
                base_matches.append({
                    "tool_id": tool_id,
                    "tool_name": tool_name,
                    "server_code": server_code,
                    "description": description
                })

        # 搜索MCP工具
        mcp_matches = []
        for tool_id, mcp_info in self.mcp_tools_dict.items():
            tool_name = mcp_info.get('tool_name', '')
            description = mcp_info.get('description', '')
            server_code = mcp_info.get('server_code', '')
            mcp_service = mcp_info.get('mcp_service', '')

            if (keyword_lower in tool_name.lower() or
                    keyword_lower in description.lower() or
                    keyword_lower in server_code.lower() or
                    keyword_lower in mcp_service.lower()):
                mcp_matches.append({
                    "tool_id": tool_id,
                    "tool_name": tool_name,
                    "server_code": server_code,
                    "mcp_service": mcp_service,
                    "description": description
                })

        return {
            "base_tools": base_matches,
            "mcp_tools": mcp_matches,
            "total_matches": len(base_matches) + len(mcp_matches)
        }

    def validate_tool_exists(self, tool_id: int = None, tool_name: str = None, tool_type: str = "base") -> bool:
        """验证工具是否存在
        
        Args:
            tool_id: 工具ID（优先级最高）
            tool_name: 工具名称
            tool_type: 工具类型（"base"或"mcp"）
            
        Returns:
            True如果工具存在，否则False
        """
        if tool_type == "base":
            if tool_id:
                return tool_id in self.base_tools_dict

        elif tool_type == "mcp":
            if tool_id:
                return tool_id in self.mcp_tools_dict

        return False

    def list_all_tools(self) -> Dict[str, Any]:
        """列出所有工具"""
        base_tools_list = []
        for tool_id, tool_info in self.base_tools_dict.items():
            base_tools_list.append({
                "tool_id": tool_id,
                "tool_name": tool_info.get('tool_name', ''),
                "server_code": tool_info.get('server_code', ''),
                "description": tool_info.get('description', '')
            })

        mcp_tools_list = []
        for tool_id, tool_info in self.mcp_tools_dict.items():
            mcp_tools_list.append({
                "tool_id": tool_id,
                "tool_name": tool_info.get('tool_name', ''),
                "server_code": tool_info.get('server_code', ''),
                "mcp_service": tool_info.get('mcp_service', ''),
                "description": tool_info.get('description', '')
            })

        return {
            "base_tools": base_tools_list,
            "mcp_tools": mcp_tools_list,
            "base_tools_count": len(self.base_tools_dict),
            "mcp_tools_count": len(self.mcp_tools_dict)
        }

    def get_tools_by_server_code(self, server_code: str) -> Dict[str, Any]:
        """根据服务代码获取工具列表
        
        Args:
            server_code: 服务代码（基础工具为category_code，MCP工具为mcp_name）
            
        Returns:
            包含匹配工具的字典
        """
        result = {
            "server_code": server_code,
            "base_tools": [],
            "mcp_tools": [],
            "total_count": 0
        }

        # 搜索基础工具
        for tool_id, tool_info in self.base_tools_dict.items():
            if tool_info.get('server_code') == server_code:
                result["base_tools"].append({
                    "tool_id": tool_id,
                    "tool_name": tool_info.get('tool_name', ''),
                    "tool_info": tool_info
                })
                result["total_count"] += 1

        # 搜索MCP工具
        for tool_id, mcp_info in self.mcp_tools_dict.items():
            if mcp_info.get('server_code') == server_code:
                result["mcp_tools"].append({
                    "tool_id": tool_id,
                    "tool_name": mcp_info.get('tool_name', ''),
                    "mcp_service": mcp_info.get('mcp_service', ''),
                    "tool_info": mcp_info
                })
                result["total_count"] += 1

        return result

    def list_all_server_codes(self) -> Dict[str, Any]:
        """列出所有服务代码"""
        base_server_codes = set()
        mcp_server_codes = set()

        # 收集基础工具的服务代码
        for tool_info in self.base_tools_dict.values():
            server_code = tool_info.get('server_code')
            if server_code:
                base_server_codes.add(server_code)

        # 收集MCP工具的服务代码
        for mcp_info in self.mcp_tools_dict.values():
            server_code = mcp_info.get('server_code')
            if server_code:
                mcp_server_codes.add(server_code)

        return {
            "base_server_codes": sorted(list(base_server_codes)),
            "mcp_server_codes": sorted(list(mcp_server_codes)),
            "all_server_codes": sorted(list(base_server_codes | mcp_server_codes)),
            "base_count": len(base_server_codes),
            "mcp_count": len(mcp_server_codes),
            "total_count": len(base_server_codes | mcp_server_codes)
        }

    async def refresh_tools_dict(self):
        """刷新工具字典"""
        print("🔄 正在刷新工具字典...")
        await self.init_global_tools_dict()
        print("✅ 工具字典刷新完成")


def get_base_tools_dict(self) -> Dict[str, Dict[str, Any]]:
    """获取基础工具字典"""
    return toolDictConfig.get_base_tools_dict()


def get_mcp_tools_dict(self) -> Dict[str, Dict[str, Any]]:
    """获取MCP工具字典"""
    return toolDictConfig.get_mcp_tools_dict()


def set_base_tools_dict(self, tools_dict: Dict[str, Dict[str, Any]]):
    """设置基础工具字典"""
    toolDictConfig.set_base_tools_dict(tools_dict)


def set_mcp_tools_dict(self, mcp_dict: Dict[str, Dict[str, Any]]):
    """设置MCP工具字典"""
    toolDictConfig.set_mcp_tools_dict(mcp_dict)


# 创建全局参数配置实例
toolDictConfig = ToolDictConfig()
